package com.keqiang.chart.base

import android.animation.ValueAnimator
import android.graphics.Canvas
import com.keqiang.chart.animation.Animator

/**
 * 图表基类
 *
 * @param D 数据类型
 * @param view 轴线图绘制在指定的View上面
 * @author Created by wanggaowan on 2022/10/31 14:06
 */
abstract class BaseChart<D>(val view: BaseChartView<*>) : IChart<D> {
    override val animator: Animator = Animator()

    private var mObservers = mutableListOf<IDataChangeObserver>()

    override fun draw(canvas: Canvas) {
        val start = view.paddingStart.toFloat()
        val top = view.paddingTop.toFloat()
        val end = (view.width - view.paddingEnd).toFloat()
        val bottom = (view.height - view.paddingBottom).toFloat()

        if (end - start <= 0 || bottom - top <= 0) {
            return
        }

        if (isEmptyData()) {
            emptyDataRender?.let {
                if (it.onDraw(canvas, start, top, end, bottom)) {
                    return
                }
            }
        }

        onDraw(canvas, start, top, end, bottom)
        customRender?.onDraw(canvas, start, top, end, bottom)
    }

    /**
     * 执行图表数据的绘制逻辑
     *
     * @param canvas 画布
     * @param start  水平可绘制区域起始点坐标
     * @param top    可绘制区域顶部坐标
     * @param end    水平可绘制区域结束点坐标
     * @param bottom 可绘制区域底部坐标
     */
    abstract fun onDraw(canvas: Canvas, start: Float, top: Float, end: Float, bottom: Float)

    override var customRender: IRender? = null

    override var emptyDataRender: IEmptyDataRender? = null

    /**
     * 图表数据
     */
    final override var data: D? = null
        set(value) {
            field = value
            mObservers.forEach {
                it.onChange()
            }
        }

    /**
     * 设置数据并通知重绘
     */
    fun setDataNotify(data: D?) {
        this.data = data
        view.invalidate()
    }

    /**
     * 刷新重绘
     */
    fun invalidate() {
        view.invalidate()
    }

    open fun animDraw(duration: Long) {
        animDraw(duration, null)
    }

    open fun animDraw(duration: Long, updateListener: ValueAnimator.AnimatorUpdateListener?) {
        animDraw(duration, updateListener, null)
    }

    /**
     * 以动画的形式进行绘制
     */
    open fun animDraw(duration: Long,
                      updateListener: ValueAnimator.AnimatorUpdateListener? = null,
                      listener: android.animation.Animator.AnimatorListener? = null) {
        animator.start(duration, updateListener = {
            view.invalidate()
            updateListener?.onAnimationUpdate(it)
        }, listener)
    }

    /**
     * 注册数据改变监听
     */
    open fun addDataChangeObserver(observer: IDataChangeObserver) {
        mObservers.add(observer)
    }

    /**
     * 移除数据改变监听
     */
    open fun removeDataChangeObserver(observer: IDataChangeObserver) {
        mObservers.remove(observer)
    }
}